import {defineConfig, globalIgnores} from "eslint/config"
import jsdoc from "eslint-plugin-jsdoc"
import jest from "eslint-plugin-jest"
import typescriptEslint from "@typescript-eslint/eslint-plugin"
import globals from "globals"
import tsParser from "@typescript-eslint/parser"
import path from "node:path"
import {fileURLToPath} from "node:url"
import js from "@eslint/js"
import {FlatCompat} from "@eslint/eslintrc"

const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)
const compat = new FlatCompat({
  baseDirectory: __dirname,
  recommendedConfig: js.configs.recommended,
  allConfig: js.configs.all
})

export default defineConfig([
  globalIgnores(["**/node_modules", "**/coverage", "**/build", "**/lib", "**/typings"]),
  {
    files: ['**/*.ts'],
    extends: compat.extends(
      "plugin:@typescript-eslint/recommended",
      "plugin:@typescript-eslint/recommended-requiring-type-checking",
    ),

    plugins: {
      jsdoc,
      jest,
      "@typescript-eslint": typescriptEslint,
    },

    languageOptions: {
      globals: {
        ...globals.node,
        ...jest.environments.globals.globals,
      },

      parser: tsParser,
      ecmaVersion: 5,
      sourceType: "module",

      parserOptions: {
        project: "./tsconfig.json",
      },
    },

    settings: {},

    rules: {
      "comma-dangle": [0],
      "guard-for-in": [0],
      "no-dupe-class-members": [0],
      "prefer-spread": [0],
      "prefer-rest-params": [0],
      "func-names": [0],
      "require-atomic-updates": [0],
      "no-empty": "off",
      "no-console": "off",
      "linebreak-style": [1, "unix"],
      "no-prototype-builtins": [0],
      "no-unused-vars": [0],
      "no-async-promise-executor": [0],
      "constructor-super": "error",
      "for-direction": ["error"],
      "getter-return": ["error"],
      "no-case-declarations": ["error"],
      "no-class-assign": ["error"],
      "no-compare-neg-zero": ["error"],
      "no-cond-assign": "error",
      "no-const-assign": ["error"],
      "no-constant-condition": ["error"],
      "no-control-regex": ["error"],
      "no-debugger": "error",
      "no-delete-var": ["error"],
      "no-dupe-args": ["error"],
      "no-dupe-keys": ["error"],
      "no-duplicate-case": ["error"],
      "no-empty-character-class": ["error"],
      "no-empty-pattern": ["error"],
      "no-ex-assign": ["error"],
      "no-extra-boolean-cast": ["error"],
      "no-extra-semi": ["error"],
      "no-fallthrough": "off",
      "no-func-assign": ["error"],
      "no-global-assign": ["error"],
      "no-inner-declarations": ["error"],
      "no-invalid-regexp": ["error"],
      "no-irregular-whitespace": "error",
      "no-misleading-character-class": ["error"],
      "no-mixed-spaces-and-tabs": ["error"],
      "no-new-symbol": ["error"],
      "no-obj-calls": ["error"],
      "no-octal": ["error"],
      "no-redeclare": "error",
      "no-regex-spaces": ["error"],
      "no-self-assign": ["error"],
      "no-shadow-restricted-names": ["error"],
      "no-sparse-arrays": "error",
      "no-this-before-super": ["error"],
      "no-undef": ["off"],
      "no-unexpected-multiline": ["error"],
      "no-unreachable": ["warn"],
      "no-unsafe-finally": "error",
      "no-unsafe-negation": ["error"],
      "no-unused-labels": "error",
      "no-useless-catch": ["error"],
      "no-useless-escape": ["error"],
      "no-with": ["error"],
      "require-yield": ["error"],
      "use-isnan": "error",
      "valid-typeof": "off",
      "jsdoc/tag-lines": "off",
      "@typescript-eslint/no-unnecessary-boolean-literal-compare": "off",
      "@typescript-eslint/no-unnecessary-type-assertion": "off",
      "@typescript-eslint/prefer-string-starts-ends-with": "off",
      "@typescript-eslint/prefer-regexp-exec": "off",
      "@typescript-eslint/adjacent-overload-signatures": "error",
      "@typescript-eslint/array-type": "off",
      "@typescript-eslint/require-await": "off",
      "@typescript-eslint/await-thenable": "error",
      "@typescript-eslint/ban-types": "off",
      "@typescript-eslint/no-unsafe-assignment": "off",
      "@typescript-eslint/no-unsafe-member-access": "off",
      "@typescript-eslint/no-unsafe-call": "off",
      "@typescript-eslint/explicit-module-boundary-types": "off",
      "@typescript-eslint/no-unsafe-return": "off",
      "@typescript-eslint/no-non-null-assertion": "off",
      "@typescript-eslint/restrict-plus-operands": "off",
      "@typescript-eslint/restrict-template-expressions": "off",
      "@typescript-eslint/consistent-type-assertions": "error",
      "@typescript-eslint/consistent-type-definitions": "error",

      "@typescript-eslint/explicit-member-accessibility": ["error", {
        accessibility: "explicit",

        overrides: {
          accessors: "explicit",
          constructors: "off",
        },
      }],

      "@typescript-eslint/interface-name-prefix": "off",
      "@typescript-eslint/member-delimiter-style": "off",
      "@typescript-eslint/camelcase": "off",
      "@typescript-eslint/member-ordering": "off",
      "@typescript-eslint/no-base-to-string": "off",
      "@typescript-eslint/no-empty-function": "off",
      "@typescript-eslint/no-empty-interface": "off",
      "@typescript-eslint/no-explicit-any": "off",
      "@typescript-eslint/no-floating-promises": "error",
      "@typescript-eslint/no-misused-promises": "off",
      "@typescript-eslint/no-for-in-array": "error",
      "@typescript-eslint/no-inferrable-types": "error",
      "@typescript-eslint/no-misused-new": "error",
      "@typescript-eslint/no-namespace": "off",
      "@typescript-eslint/no-parameter-properties": "off",
      "@typescript-eslint/no-redundant-type-constituents": "off",
      "@typescript-eslint/no-unused-vars": "off",
      "@typescript-eslint/no-unnecessary-qualifier": "error",
      "@typescript-eslint/no-unsafe-enum-comparison": "off",
      "@typescript-eslint/no-use-before-define": "off",
      "@typescript-eslint/no-unsafe-argument": "off",
      "@typescript-eslint/explicit-function-return-type": "off",
      "@typescript-eslint/no-var-requires": "off",
      "@typescript-eslint/prefer-for-of": "off",
      "@typescript-eslint/prefer-function-type": "off",
      "@typescript-eslint/prefer-namespace-keyword": "error",
      "@typescript-eslint/quotes": "off",
      "@typescript-eslint/no-require-imports": "off",
      "@/semi": ["error", "never"],

      "@typescript-eslint/triple-slash-reference": ["error", {
        path: "always",
        types: "prefer-import",
        lib: "always",
      }],

      "@typescript-eslint/unbound-method": "off",
      "@typescript-eslint/unified-signatures": "error",
      "arrow-body-style": "off",
      "arrow-parens": ["error", "as-needed"],
      camelcase: "off",
      complexity: "off",
      curly: "off",
      "dot-notation": "off",
      "eol-last": "off",
      eqeqeq: ["off", "always"],

      "id-blacklist": [
        "error",
        "any",
        "Number",
        "number",
        "String",
        "string",
        "Boolean",
        "boolean",
        "Undefined",
      ],

      "id-match": "error",
      "jsdoc/check-alignment": "error",
      "jsdoc/check-indentation": "error",
      "jsdoc/tag-lines": 1,
      "max-classes-per-file": "off",
      "new-parens": "error",
      "no-bitwise": "off",
      "no-caller": "error",
      "no-eval": "error",
      "no-invalid-this": "off",
      "no-magic-numbers": "off",

      "no-multiple-empty-lines": ["error", {
        max: 1,
      }],

      "no-new-wrappers": "error",

      "no-shadow": ["off", {
        hoist: "all",
      }],

      "no-template-curly-in-string": "off",
      "no-throw-literal": "error",
      "no-trailing-spaces": "error",
      "no-undef-init": "error",
      "no-underscore-dangle": "off",
      "no-unused-expressions": "off",
      "no-var": "error",
      "no-void": "off",
      "object-shorthand": "error",
      "one-var": ["error", "never"],
      "prefer-const": "off",
      "prefer-template": "off",
      "quote-props": ["error", "as-needed"],
      radix: "error",

      "space-before-function-paren": ["error", {
        anonymous: "never",
        asyncArrow: "always",
        named: "never",
      }],

      "spaced-comment": ["error", "always", {
        markers: ["/"],
      }],
    },
  }, {
    files: ['src/__tests__/**/*.ts'],
    rules: {
      "@typescript-eslint/no-unsafe-function-type": "off"
    }
  }
])
